<?php
$loader->requireOnce('controllers/C_Patient.class.php');
$loader->requireOnce('ordo/Province.class.php');
$loader->requireOnce('ordo/Insurance.class.php');
$loader->requireOnce('includes/PatientRegistration.class.php');
$loader->requireOnce('includes/PaymentException.class.php');

/**
 * Controller of all actions related to reception tasks of Emergency department

 * @package modules.dept_emer.controllers
 * @author LHV
 * @version $Id$
 * @copyright 2009 LHV Company
 *
 */
class C_OdonReception extends Controller {
    private $logger;

    function C_OdonReception($template_mod = "general") {
        parent::Controller();
        $this->logger = LoggerManager::getLogger('module.dept_odontology.controllers.C_OdonReception');
        $this->template_mod = $template_mod;
        $this->view->path="odon_reception";
    }
    
    /**
     * Registration form for insurance patient
     * @return HTML
     */
    public function actionRegisterInsurancePatient() {
        $this->assign('insurance', 1);
        $this->assignDemographicInfo();
        return $this->view->render("add_demographics.html");
    }

    /**
     * Load page to input reception info.
     *
     */
    public function actionRegister(){
        $this->assign('insurance', 0);
        $this->assignDemographicInfo();
        return $this->view->render("add_demographics.html");
    }
    
    /**
     * Clear form
     */
    public function actionCancel($insurance = 0) {
        if (isset($_POST['insurance'])) {
            $insurance = $_POST['insurance'];
        }
        $this->assign('insurance', $insurance);
        $this->assignDemographicInfo();
        return $this->view->render("add_demographics.html");
    }

   
    /**
     * Load page to input reception info.
     *
     * @param int $patientId
     * @param int $insurance
     *      = 0:    load demographics
     *      = 1:    load demographics + insurance info
     */
    public function actionLoadPatientAjax($patientId = 0, $insurance = 0){
        if (isset($_POST['patientId'])) {
            $patientId = $_POST['patientId'];
        }
        
        if (isset($_POST['insurance'])) {
            $insurance = $_POST['insurance'];
        }
        
        $this->assignDemographicInfo($patientId);
        $this->assignInsuranceInfo($patientId);
        $this->assign('insurance', $insurance);
        $this->assign('treatmentDurationHtml', $this->treatmentDurationHtml($patientId));
        return $this->view->render("edit_demographics.html");
    }
    
    public function actionLoadReadOnlyPatientAjax($patientId = 0, $insurance = 0){
        if (isset($_POST['patientId'])) {
            $patientId = $_POST['patientId'];
        }
        
        if (isset($_POST['insurance'])) {
            $insurance = $_POST['insurance'];
        }
        
        $this->assignDemographicInfo($patientId);
        $this->assignInsuranceInfo($patientId);
        $this->assign('insurance', $insurance);
       // $this->assign('treatmentDurationHtml', $this->treatmentDurationHtml($patientId));
        return $this->view->render("read_only_demographics.html");
    }


    /**
     * Saving patient info and register examination
     * @return unknown_type
     */
    public function actionRegisterPatientAjax() {
        $result = array('error'=>array('code'=>CoreErrorCode::NORMAL,'mess'=>''),
        'result'=>array('code'=>'','id'=>'','ticket_id'=>''));
        
        $rs = $this->savePatientInfo();
        
        try {
            $patientRegistrationObj = new PatientRegistration();
            if ($rs['id'] != '') {
                $rs1 = $patientRegistrationObj->registerTreatment($rs['id'], $this->_me->get_department_id(), $_POST['insurance']);
                if ($rs1['ticketId'] == '') {
                    $result['error']['code'] = OdonErrorCode::ADMISSION_REGISTER_FAIL;
                    $result['error']['mess'] = OdonErrorCode::getErrorMess(OdonErrorCode::ADMISSION_REGISTER_FAIL);
                    $logger->error('actionRegisterPatientAjax fail. Error detail: '. $ex->getMessage());
                }
                $result['result']['code'] = $rs['code'];
                $result['result']['id'] = $rs['id'];
                $result['result']['ticket_id'] = $rs1['ticketId'];
                $result['result']['recordId'] = $rs1['recordId'];
            } else {
                $result['error']['code'] = OdonErrorCode::ADMISSION_REGISTER_FAIL;
                $result['error']['mess'] = OdonErrorCode::getErrorMess(OdonErrorCode::ADMISSION_REGISTER_FAIL);
                $logger->error('actionRegisterPatientAjax fail. Error detail: '. $ex->getMessage());
            }
        } catch (HISFileLoaderException $ex) {
            $result['error']['code'] = OdonErrorCode::ADMISSION_REGISTER_FAIL;
            $result['error']['mess'] = OdonErrorCode::getErrorMess(OdonErrorCode::ADMISSION_REGISTER_FAIL);
            $this->logger->error('actionRegisterPatientAjax fail. Error detail: '. $ex->getMessage());
        }

        return json_encode($result);
    }

    /**
     * Only save patient information, do not register for examination
     */
    public function actionSavePatientAjax() {
        $result = array('error'=>array('code'=>CoreErrorCode::NORMAL,'mess'=>''),
                        'result'=>array());
        
        $rs = $this->savePatientInfo();
        $result['result']['code'] = $rs['code'];
        $result['result']['id'] = $rs['id'];
        
        return json_encode($result);
    }

    /**
     * Print patient info
     */
    public function actionPrintTreatmentTicket() {
        $recordId = '';
        $patientId = '';
        $codePrefix = '';
        
        if (isset($_GET['patientId'])) {
            $patientId = $_GET['patientId'];

        }
        if (isset($_GET['recordId'])) {
            $recordId = $_GET['recordId'];

        }
        if (isset($_GET['codePrefix'])) {
            $codePrefix = $_GET['codePrefix'];
        }        

        $orders =   L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);
        
        $this->assign('codePrefix', $codePrefix);        

        $person = ORDataObject::factory('Person');
        $person->setup($patientId);
        
        $patient = ORDataObject::factory('Patient');
        $patient->setup($patientId);

        $this->assign('person', $person);
        $this->assign('patient', $patient);
        
        $countryList = ORDataObject::factory('Country')->getCountryListForSelect();
        $this->assign('country', $countryList[$person->get('nationality')]);
        
        $careerList = $this->getCareerList();
        $this->assign('career', $careerList[$person->getCareer()]);

        $birthDay = L10nHelper::renderDateTime($person->get('date_of_birth'),'short', 'date');
        $this->assign('birthDays', $birthDay);
        $this->assign('examTime', date('H:i'));
        
        return $this->view->render("demographics_print.html");
    }


    // TODO ptnguyen 2010-04-05
    // Should move autocomplete code to another places
    /**
     * For autocomplele
     */
    public function actionGetDistrictFromProvinceAjax() {
        $districtList=& ORDataObject::factory('District')->getDistrictList($_GET['proviceId']);
        $response['districtList'] = "";

        foreach ($districtList as $key=>$value) {
            $response['districtList'] .= "<option value=\"$key\">$value</option>";
        }
        echo json_encode($response);
    }
    
    /**
     * For autocomplete
     */
    public function actionGetWardFromDistrictAjax() {

        $districtId     =   $_GET['districtId'];
        $wardObj = Celini::newOrdo('Ward');
        $wardList = $wardObj->getAllWards($districtId);
        foreach ($wardList as $ward) {
            echo $ward['name'] . "\n";
        }
    }
    
    
    /**
     * Delete patient
     * @param unknown_type $patientId
     */
    public function actionDeletePatientAjax($patientId = 0) {
        $result    =   array(
           'error'     =>  array('code' => CoreErrorCode::NORMAL, 'mess' =>  ''),
           'result'    =>  array('type' => '', 'html' => '')
        );
        if (isset($_POST['patientId'])) {
            $patientId  =   $_POST['patientId'];
        }
       
        $this->logger->info("Start action DeletePatientAjax {patientId='$patientId'}");
        try {
            // Check if the patient already has had payment info
            $paymentList =   Celini::newORDO('PayPayment')->getPaymentInfoByPatient($patientId);
            $recNum  =   count($paymentList);
            $this->logger->debug("Patient's payment records: patientId = '$patientId', recordNum = '$recNum'");
            if ($recNum > 0) {
                // Commmented by ppdong 2010-03-01: Not alllow to deleted patients having payment info
            	throw new PaymentException("Patient id=$patientId has had payment infomation", PaymentErrorCode::DELETE_PATIENT_HAVING_PAYMENT_INFO);
            }
            else {
                $objReg	=	new PatientRegistration();
                $objReg->deletePatient($patientId);
            }
        }
        catch (Exception $ex) {
            $result['error']['code']	=	$ex->getErrorCode();
            $result['error']['mess']	=	PaymentErrorCode::getErrorMess($ex->getErrorCode());
            $this->logger->error("Action DeletePatientAjax {patientId='$patientId'} failed. Error: " . $ex->getMessage());
        }
        $this->logger->info("End action DeletePatientAjax {patientId='$patientId'}");

        return json_encode($result);
    }
        
    
    /**
     * Save patient info.
     *
     * Including normal or insurance patient
     */
    private function savePatientInfo() {
        $arrPerson = array ();
        $arrPerson['name'] = Utils::sanitizeAndCaseTitle($_POST['person']['name']);
        $dates['year']  =   (int)Utils::sanitizeText($_POST['person']['DOB_yyyy']);
        $dates['month'] =   (int)Utils::sanitizeText($_POST['person']['DOB_mm']);
        $dates['day']   =   (int)Utils::sanitizeText($_POST['person']['DOB_dd']);
        $arrPerson['date_of_birth']    =   L10nHelper::getISODate($dates);
        $arrPerson['gender'] = $_POST['person']['gender'];
        $arrPerson['nationality'] = $_POST['person']['nationality'];
        $arrPerson['phone_number'] = $_POST['person']['phoneNumber'];
        $arrPerson['career_id'] = $_POST['person']['careerId'];

        $arrAddress = array();
        $arrAddress['street'] =  Utils::sanitizeAndCaseTitle($_POST['address']['street']);
        $arrAddress['province_id'] =  $_POST['address']['provinceId'];
        $arrAddress['district_id'] =  $_POST['address']['districtId'];
        $arrAddress['ward_name'] =  Utils::sanitizeAndCaseTitle($_POST['address']['wardName']);

        $arrPatient = array();
        $arrPatient['relative_name'] = Utils::sanitizeAndCaseTitle($_POST['patient']['relativeName']);
        $arrPatient['relative_number'] = Utils::sanitizeAndCaseTitle($_POST['patient']['relativeNumber']);
        //$arrPatient['patient_code'] = Utils::sanitizeAndCaseTitle($_POST['patient']['patient_code']);
        
        $registrationInfoObj = new RegistrationInfo($_POST['patient']['id'], $_POST['patient']['patient_code']);
        $registrationInfoObj->setPersonData($arrPerson);
        $registrationInfoObj->setPersonAddressData($arrAddress);
        $registrationInfoObj->setPatientData($arrPatient);
        
        if (isset($_POST['insurance']) && $_POST['insurance'] == 1) {
            // Insurance data was saved by ajax
            $arrInsurance = array();

            $insuranceCode  =   $_POST['insuranceCode_0'] . '-' .
                                $_POST['insuranceCode_1'] . '-' .
                                $_POST['insuranceCode_2'] . '-' .
                                $_POST['insuranceCode_3'] . '-' .
                                $_POST['insuranceCode_4'] . '-' .
                                $_POST['insuranceCode_5'];
            $issuedDate['year']    =   (int)Utils::sanitizeText($_POST['issued_yyyy']);
            $issuedDate['month']   =   (int)Utils::sanitizeText($_POST['issued_mm']);
            $issuedDate['day']     =   (int)Utils::sanitizeText($_POST['issued_dd']);
            $issuedDate            =   L10nHelper::getISODate($issuedDate);

            $expiredDate['year']   =   (int)Utils::sanitizeText($_POST['expired_yyyy']);
            $expiredDate['month']  =   (int)Utils::sanitizeText($_POST['expired_mm']);
            $expiredDate['day']    =   (int)Utils::sanitizeText($_POST['expired_dd']);
            $expiredDate           =   L10nHelper::getISODate($expiredDate);

            $correctRoute = (isset($_POST['correctRoute']) && $_POST['correctRoute'] == 'on') ? 1 : 0;
            $paidFor36Month = (isset($_POST['paidFor36Month']) && $_POST['paidFor36Month'] == 'on') ? 1 : 0;

            $hospitalId     =   Utils::sanitizeAndCaseTitle($_POST['registeredHospitalId']);

            $arrInsurance[] = array('insurance_code'    => $insuranceCode,
                                'date_issued'       => $issuedDate,
                                'date_expired'      => $expiredDate,
                                'registered_hospital_id'    => $hospitalId,
                                'correct_route'     => $correctRoute,
                                'paid_for_36_month' => $paidFor36Month);
             

            $registrationInfoObj->setInsuranceData($arrInsurance);
        }
                
        $patientRegistrationObj = new PatientRegistration();
        return $patientRegistrationObj->registerPatientInfo($registrationInfoObj);
    }
    
    //////////////////////////////////  PRIVATE FUNCTIONS ////////////////////////////////
    
    /**
     * Assign insurance infor
     * @param $patientId
     * @return unknown_type
     */
    private function assignInsuranceInfo($patientId = 0) {
        $insuranceObj = Insurance::fromPatientId($patientId);
        
        $insuranceCode = array();
        $issuedDate = array();
        $expiredDate = array();
        $hospitalName = '';
        if ($insuranceObj->get_id() > 0) {
            $insuranceCode = explode('-', $insuranceObj->get('insurance_code'));
            $date = DateObject::createFromISO($insuranceObj->get('issued_date'));
                        
            $issuedDate =   L10nHelper::getDateParts($insuranceObj->getLocalizedDate('date_issued'));
            $expiredDate =   L10nHelper::getDateParts($insuranceObj->getLocalizedDate('date_expired'));
            $hospitalName = $insuranceObj->getRegisteredHospitalName();
        }
        
        $orders =   L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);
        $this->assign('date_issued', $issuedDate);
        $this->assign('date_expired', $expiredDate);
        $this->assign('hospitalName', $hospitalName);
        $this->assign('insuranceCode', $insuranceCode);
        
        $this->assign('insuranceId', $insuranceObj->get_id());
        $this->assign('registeredHospitalId', $insuranceObj->get('registered_hospital_id'));
        $this->assign('correctRoute', $insuranceObj->get('correct_route'));
        $this->assign('paidFor36Month', $insuranceObj->get('paid_for_36_month'));
        
        //var_dump($patientId);
        //var_dump($insuranceCode);
    }
    
    private function assignDemographicInfo($patientId = 0) {
        /**
         * For insurance component
         */
        $this->assign('patientId', $patientId);
        
        $person = ORDataObject::factory('Person', $patientId);
        $patient = ORDataObject::factory('Patient', $patientId);
        $this->assign('person', $person);
        $this->assign('patient', $patient);
        
        $birthDay =  L10nHelper::getDateParts(
                            L10nHelper::renderDateTime($person->get('date_of_birth'),'short', 'datetime'));
        $this->assign('birthDays', $birthDay);
        
        $countryList = ORDataObject::factory('Country')->getCountryListForSelect();
        $selectedNationality = ($patientId == 0) ? 1 : $person->get('nationality');
        $this->assign('countryList', $countryList);
        $this->assign('selectedNationality', $selectedNationality);
        
        $careerList = $this->getCareerList();
        $careerAutoSuggestList =&  ORDataObject::factory('Career')->getCareerListAutoSuggest();
        
        
        $this->assign('careerList', $careerList);
        $this->assign('careerAutoSuggestList', $careerAutoSuggestList);
        
        $orders =   L10nHelper::getYMDorder();
        $this->assign('datePart_0', $orders[0]);
        $this->assign('datePart_1', $orders[1]);
        $this->assign('datePart_2', $orders[2]);

        $date =  L10nHelper::getDateParts(
        L10nHelper::renderDateTime(date('Y-m-d H:i:s'),'short', 'datetime'));
        $defaultcodePrefix = substr($date[2],2,2);
        $this->assign('defaultcodePrefix', $defaultcodePrefix);
                                        
        $provinceId = ($patientId == 0) ? Province::HCM_PROVINCE_ID : $person->getProvinceId();
        $districtId = ($patientId == 0) ? Province::HCM_DISTRICT_1_ID : $person->getDistrictId();
        $provinceList =& ORDataObject::factory('Province')->getProvinceList();
        $districtList =& ORDataObject::factory('District')->getDistrictList($provinceId);
        $this->assign('provinceList', $provinceList);
        $this->assign('selectedProvince', $provinceId);
        $this->assign('districtList', $districtList);
        $this->assign('selectedDistrict', $districtId);
    }
 
    public function getCareerList() {
        $careerList =&  ORDataObject::factory('Career')->getCareerListForSelect();
        $orderedCareerList = array();
        $temp = array();
        $joblessId = Career::JOBLESS;
        foreach ($careerList as $id=>$name) {
            if ($id != $joblessId) {
                $orderedCareerList[$id] = $name;
            } else {
                $temp[$id] = $name;
            }
        }
        if(!empty($temp)){
            $orderedCareerList[$joblessId] = $temp[$joblessId];
        }
        return $orderedCareerList;
    }

    public function actionGetAreaInfo() {
        if (!isset($_POST['wardId'])) {
            return;
        }

        $result['district_option'] = '';
        $wardId = $_POST['wardId'];
        $wardObj = Celini::newOrdo('Ward');
        $result['area_info'] = $wardObj->getAreaInfo($wardId);

        $districtList=& ORDataObject::factory('District')->getDistrictList($result['area_info']['province_id']);
        $response = "";
        foreach ($districtList as $key=>$value) {
            $response .= "<option value=\"$key\">$value</option>";
        }

        $result['district_option'] = $response;
        return json_encode($result);
    }
    
    /**
     * Render the summary of patient treatment duration
     * @param $patientId
     * @return HTML
     */
    private function treatmentDurationHtml($patientId) {
        if ($patientId == 0) {
            return '';
        }
        
        $record = Celini::newORDO('MedicalRecord');
        $res = $record->getTreatmentHistory($patientId);
        
        $tbodyOpen = array();
        $tbodyClose = array();
        $tbodyOpen[] = '<ul><li class="header">' . L10nHelper::_('Open Record') . '<ul>';
        $tbodyClose[] = '<ul><li class="header">' . L10nHelper::_('Closed Record') . '<ul>';
        $arr = array();

        $today = date('Y-m-d');
        
        foreach ($res as $item) {
            $diagnosis = '';
            $icd = Celini::newOrdo('Icd10')->getObjectbyCode($item['primary_icd10']);
            if ($icd->get_id() > 0) {
                $diagnosis = ' - ' . $icd->getLocalizedText('name');
            }
            
            if ($item['iso_date'] == $today) {
                $tbodyOpen[$item['ticket_id']] .= '<li>' . L10nHelper::renderDateTime($item['iso_date']) . $diagnosis . '</li>';
            } else {
                $tbodyClose[$item['ticket_id']] .= '<li>' . L10nHelper::renderDateTime($item['iso_date']) . $diagnosis . '</li>';
            }

        }

        return implode('', $tbodyOpen) . '</ul></li></ul>' . implode('', $tbodyClose) . '</ul></li></ul>';
    }
    
}
?>